#!/usr/bin/python
# Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
# Any live cell with more than three live neighbours dies, as if by overcrowding.
# Any live cell with two or three live neighbours lives on to the next generation.
# Any dead cell with exactly three live neighbours becomes a live cell.

cells = {}
dead_list = [] # lolz, global varibles. Bad, I know. Will be fixed later.

def show_field(): # this can be changed to dispaly whatever section of the board you want, stretching to infinity
    bookends = ("| " + (" - "*20)+ " |")
    print(bookends)
    for y in range(1,21):
        line = ""
        for x in range(1,21):
            if (x,y) in cells:
                line += str(cells[x,y]) + " "
            else:
                line = line + " . "
        print("| " + line + " |")
    print(bookends)

def check_adjacent(cell, skip=False): # "skip" is used to skip the live cell only bits when checked dead cells
    global dead_list
    number_adjcant = 0 # of adjaenct cells
    for x in range(-1,2):
        for y in range(-1,2):
            if (cell[0]+x, cell[1]+y) in cells:
                number_adjcant += 1
            else:
                if skip == False: dead_list.append((cell[0]+x, cell[1]+y)) # adds the dead ajacent cell to dead_list
    if skip == False: number_adjcant -= 1 # because we don't want a live cell reporting itself as a neighbor
    return (number_adjcant)

def rules():
    global cells
    global dead_list 
    dead_list = [] # resets the dead list
    cells_copy = dict(cells) # so it doesn't update the board while still iterating through it, which would screw things up
    for cell in cells:
        if   check_adjacent(cell) < 2 and cell in cells:
            del cells_copy[cell]
        elif check_adjacent(cell) > 3 and cell in cells:
            del cells_copy[cell]
        elif check_adjacent(cell) in [2,3] and cell in cells:
            cells_copy[cell] += 1
    for dead_cell in dead_list: # iterates over all dead cells that are adjacent to a live cell
        if check_adjacent(dead_cell, True) == 3:
            cells_copy[dead_cell] = 0
    cells = cells_copy

starting_cells = [(10,9), (10,10), (11,9), (11,10), (12,11), (12,12), (13,11), (13,12)]

for cell in starting_cells:
    cells[(cell)] = 0 # the number is the number of generations the cell has survived

while True:
    show_field()
    rules()
    raw_input()
